package cn.darkhorse.workflow.core;


import cn.darkhorse.exception.ServiceException;
import cn.darkhorse.workflow.auto.entity.ConfirmApproval;
import cn.darkhorse.workflow.service.IBpmnAgentExtService;
import cn.darkhorse.workflow.service.IBpmnAlreadyDealtTaskExtService;
import cn.darkhorse.workflow.service.IWorkflowToolService;
import cn.darkhorse.workflow.tool.BusinessConstants;

import cn.darkhorse.workflow.tool.WorkflowConstants;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.Map;

/**
 * 封装审批相关操作
 * @author yuanjun
 * @since 2020/7/20 11:56
 */
public class BaseApproval<T> implements IApproval<T> {
   
   /* @Resource
    IMessageService messageService;
      @Resource
    IWorkflowToolService workflowToolService;
    */
    @Resource
    IWorkflowToolService toolService;
    @Resource
    private IBpmnAgentExtService iBpmnAgentExtService;
    @Resource
    private IBpmnAlreadyDealtTaskExtService alreadyDealtTaskExtService;
    
    /**
     * 开始一个审批流程
     * @param iService mp对应的IService接口，
     * @param businessId
     * @param workflowId
     * @param workflowType
     * @param businessName 待审批列表要展示的业务单据名称  例  编码xxxx+名称xxxx
     * @return
     */
    @Transactional
    @Override
    public void startApproval(IService iService, String businessId, String businessName,String workflowId, WorkflowType workflowType,String userName){
        // 判断业务表单是否存在
        T t = (T) iService.getById(businessId);
        if (null == t) {
            //return "无业务单据数据！";
            throw new ServiceException("无业务单据数据！");
        }
        String code;
        String name;
        //添加待办事项
        iBpmnAgentExtService.add(Long.valueOf(businessId),workflowType.getType(),businessName);
    
        // 开始一个工作流
        String processInstance = toolService.startProcessInstance(workflowType.name() + ":" + businessId, workflowId, getClazz(), t, workflowType.getType().toString(),userName);

        // 更新业务表单状态为：审核中
        try {
            Field field = t.getClass().getDeclaredField(BusinessConstants.toCamelCase(BusinessConstants.FIELDNAME_AUDIT_STATUS));
            field.setAccessible(true);
            try {
                field.set(t,Integer.valueOf(BusinessConstants.AUDIT_STATUS_UNDER_REVIEW));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                throw new ServiceException(e.getMessage());
            }
            iService.saveOrUpdate(t);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
        code = fieldValue(t, BusinessConstants.FIELDNAME_CODE);
        name = fieldValue(t, BusinessConstants.FIELDNAME_NAME);
        //添加已办事项
        alreadyDealtTaskExtService.add(processInstance, userName,workflowType.getType().toString(),
                businessId.toString(),name,code,0);
    }
    
  
    @Transactional
    @Override
    public void doApproval(IService iService,ConfirmApproval confirmApproval,WorkflowType workflowType, IOpinion opinion) {
        // 判断业务表单是否存在
        T t = (T) iService.getById(confirmApproval.getBusinessId());
        if (null == t) {
            throw new ServiceException("无业务单据数据！");
        }
        String code  = null;
        String name  = null;
        Map<String,Object> result = toolService.confirmApproval(confirmApproval, workflowType.getType().toString());
        boolean conclusion = (Boolean)result.get("result");
        int resultType = Integer.parseInt(result.get("resultType").toString());
        int resultValue = Integer.parseInt(result.get("resultValue").toString());
        Long businessId = Long.valueOf(String.valueOf(result.get("businessId")));
        if(conclusion&&resultType>0&&resultValue>-1){
            if(WorkflowConstants.AGREE == resultType){
                //同意
                opinion.agree(businessId);
            }else if(WorkflowConstants.DISAGREE == resultType){
                //不同意
                opinion.disagree(businessId);
            }else if(WorkflowConstants.PROCESS_AGREE == resultType){
            }else{
                // 拒绝
                opinion.veto(businessId);
            }
            //TODO 20210907 明确只有同意才会通知
            if(WorkflowConstants.PROCESS_AGREE == resultType || WorkflowConstants.AGREE == resultType){
                //添加通知人信息
              /*  String activityName = workflowToolService.activityIds(confirmApproval.getProcessInstanceId());
                if(StringUtils.isNotBlank(activityName)){
                    addPmMessage(businessId,workflowType,activityName,confirmApproval.getProcessInstanceId());
                }*/
            }
            
        }else if(!conclusion){
            throw  new ServiceException("参数错误");
        }
        //删除待办事项
        iBpmnAgentExtService.delete(Long.valueOf(confirmApproval.getBusinessId()),workflowType.getType(),confirmApproval.getProcessInstanceId());
       //编码  无字段删除
        code = fieldValue(t, BusinessConstants.FIELDNAME_CODE);
        //名称  无字段删除
        name = fieldValue(t, BusinessConstants.FIELDNAME_NAME);
        //添加已办事项
        alreadyDealtTaskExtService.add(confirmApproval.getProcessInstanceId(), confirmApproval.getUserName(),workflowType.getType().toString(),
               confirmApproval.getBusinessId(),name,code,(confirmApproval.getType() == 2 || confirmApproval.getType() == 3) ? 1 : 0);
    }
    
    
    /**
     * 获取字段值
     * @param t
     * @param field
     * @return
     */
    private String fieldValue(T t,String field){
        String value;
        try {
            //获取  无字段封掉
            Field codeField = t.getClass().getDeclaredField(BusinessConstants.toCamelCase(field));
            codeField.setAccessible(true);
            try {
                //获取字段 无字段封掉
                value = String.valueOf(codeField.get(t));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                throw new ServiceException(e.getMessage());
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
        return value;
    }
    
    
    
    
    
    private Class<T> getClazz() {
        Class<T> tClass = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        return tClass;
    }
    
    /**
     *添加通知人信息
     * @param businessId
     * @param businessType
     * @param taskKey
     */
  /*  private void addPmMessage(Long businessId, cn.darkhorse.pm.core.workflow.WorkflowType businessType, String taskKey, String workflowExampleId){
        List<PmMessage> messages = new ArrayList<>();
        String title = "";
        //获取审批表单名称
        LambdaQueryWrapper<BpmnAgent> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BpmnAgent::getBusinessId,businessId).eq(BpmnAgent::getBusinessType,businessType.getType());
        List<BpmnAgent> agentList = agentService.list(wrapper);
        if(null != agentList && !agentList.isEmpty()){
            title = agentList.get(0).getBusinessName();
        }
        //获取通知人员
        List<String> notifier = toolService.getNotifier(taskKey);
        if(null != notifier && !notifier.isEmpty()){
            for(String s:notifier){
                String username = s.replaceAll("\"", "");
                PmMessage message = new PmMessage();
                message.setBusinessId(businessId).setBusinessType(businessType.name()).setTitle(title).setNotifier(username)
                        .setIsDelete(CommonConstant.IS_DELETE_NO).setIsRead(CommonConstant.IS_DELETE_NO).setCreateTime(LocalDateTime.now())
                        .setWorkflowExampleId(workflowExampleId);
                messages.add(message);
            }
        }
        messageService.batchAdd(messages);
    }*/
    
   
}
